home *** CD-ROM | disk | FTP | other *** search
/ Aminet 35 / Aminet 35 (2000)(Schatztruhe)[!][Feb 2000].iso / Aminet / util / misc / ReportPlus.lha / ReportPlus / Source / rp.c next >
Encoding:
C/C++ Source or Header  |  1999-12-11  |  49.2 KB  |  2,017 lines

  1. /* $Filename:        WormWars/Source/rp.c $
  2.  * $VER:            Report+ 1.1 (11.12.99) $
  3.  * $Description:    Bug report/Aminet readme generator $
  4.  *
  5.  * © Copyright 1999 James R. Jacobs. Freely distributable.
  6.  *        _
  7.  *       //        -=AMIGA=-
  8.  *      //
  9.  * _   //
  10.  * \\ //
  11.  *  \X/
  12.  *
  13.  * Release version.
  14.  
  15. #INCLUDES -------------------------------------------------------------- */
  16.  
  17. #include "rp.h"                 // #includes everything else
  18.  
  19. IMPORT    struct Library*            SysBase;
  20. MODULE    struct ASLBase*            ASLBase                            = NULL;
  21. MODULE    struct GadToolsBase*    GadToolsBase                    = NULL;
  22. MODULE    struct GfxBase*            GfxBase                            = NULL;
  23. MODULE    struct IntuitionBase*    IntuitionBase                    = NULL;
  24.  
  25. MODULE    TEXT                    aslresult[MEDFIELD + 1],
  26.                                 string[VLONGFIELD + 1],
  27.                                 IOBuffer[4096];
  28. MODULE    ULONG                    offset;
  29. MODULE    SBYTE                    page = 0;
  30. MODULE    struct TextFont*        FontPtr                            = NULL;
  31. MODULE    APTR                    OldWindowPtr                    = NULL;
  32. MODULE    struct Window            *BkgrndWindowPtr                = NULL,
  33.                                 *MainWindowPtr                    = NULL;
  34. MODULE    struct Menu*            MenuPtr                            = NULL;
  35. MODULE    struct List                List1, List2;
  36. MODULE    struct Process*            ProcessPtr                        = NULL;
  37.  
  38. MODULE    struct Gadget            // misc
  39.                                 *GListPtr                        = NULL,
  40.                                 *NextGadPtr                        = NULL,
  41.                                 *PrevGadPtr                        = NULL,
  42.                                 *PreviousGadPtr                    = NULL,
  43.                                 *OutputGadPtr                    = NULL,
  44.                                 *OutputASLGadPtr                = NULL,
  45.  
  46.                                 // page 0
  47.                                 *FunctionGadPtr                    = NULL,
  48.                                 *EditorGadPtr                    = NULL,
  49.                                 *EditorASLGadPtr                = NULL,
  50.  
  51.                                 // page 1
  52.                                 *SummaryGadPtr                    = NULL,
  53.                                 *TypeGadPtr                        = NULL,
  54.  
  55.                                 // page 2
  56.                                 *DebugGadPtr                    = NULL,
  57.                                 *KSGadPtr                        = NULL,
  58.                                 *SubsystemGadPtr                = NULL,
  59.                                 *PPGadPtr                        = NULL,
  60.                                 *PPASLGadPtr                    = NULL,
  61.                                 *PVGadPtr                        = NULL,
  62.                                 *SeverityGadPtr                    = NULL,
  63.                                 *ThirdGadPtr                    = NULL,
  64.                                 *ThirdNameGadPtr                = NULL,
  65.                                 *ThirdVerGadPtr                    = NULL,
  66.                                 *ThirdManufGadPtr                = NULL,
  67.                                 *WBGadPtr                        = NULL,
  68.  
  69.                                 // page 3
  70.                                 *CompanyGadPtr                    = NULL,
  71.                                 *DeveloperGadPtr                = NULL,
  72.                                 *EMailGadPtr                    = NULL,
  73.                                 *FirstNameGadPtr                = NULL,
  74.                                 *LastNameGadPtr                    = NULL,
  75.                                 *PhoneGadPtr                    = NULL,
  76.  
  77.                                 // page 4
  78.                                 *ModelGadPtr                    = NULL,
  79.                                 *ModelTextGadPtr                = NULL,
  80.                                 *AgnusGadPtr                    = NULL,
  81.                                 *AgnusTextGadPtr                = NULL,
  82.                                 *CPUGadPtr                        = NULL,
  83.                                 *CPUTextGadPtr                    = NULL,
  84.                                 *DeniseGadPtr                    = NULL,
  85.                                 *DeniseTextGadPtr                = NULL,
  86.                                 *FloppiesGadPtr                    = NULL,
  87.                                 *ChipGadPtr                        = NULL,
  88.                                 *ChipTextGadPtr                    = NULL,
  89.                                 *FastGadPtr                        = NULL,
  90.                                 *FastTextGadPtr                    = NULL,
  91.                                 *HardGadPtr                        = NULL,
  92.                                 *ExpansionGadPtr                = NULL,
  93.  
  94.                                 // page 6
  95.                                 *ShortGadPtr                    = NULL,
  96.                                 *UploaderGadPtr                    = NULL,
  97.                                 *AuthorGadPtr                    = NULL,
  98.                                 *RequiresGadPtr                    = NULL,
  99.                                 *VersionGadPtr                    = NULL,
  100.                                 *DistributionGadPtr                = NULL,
  101.                                 *AmiTypeGadPtr                    = NULL,
  102.                                 *ReplacesGadPtr                    = NULL;
  103.  
  104. MODULE    struct Screen*            ScreenPtr                        = NULL;
  105. MODULE    struct VisualInfo*        VisualInfoPtr                    = NULL;
  106. MODULE    struct TextAttr            Topaz8 =
  107. {    (STRPTR) "Topaz.font", 8, FS_NORMAL, FPF_ROMFONT | FPF_DESIGNED
  108. };
  109.  
  110. // FUNCTIONS --------------------------------------------------------------
  111.  
  112. int main(int argc, char** argv)
  113. {    UWORD                    Pens[10] =
  114.     {    BLACK,        // DETAILPEN        text in title bar
  115.         WHITE,        // BLOCKPEN            fill title bar
  116.         BLACK,        // TEXTPEN            regular text on BACKGROUNDPEN
  117.         WHITE,        // SHINEPEN            bright edge
  118.         BLACK,        // SHADOWPEN        dark edge
  119.         RED,        /* FILLPEN            filling active window borders
  120.                                         and selected gadgets */
  121.         BLACK,        // FILLTEXTPEN        text rendered over FILLPEN
  122.         LIGHTGREY,    // BACKGROUNDPEN    background colour
  123.         WHITE,        // HIGHLIGHTTEXTPEN    highlighted text on BACKGROUNDPEN
  124.         (UWORD) ~0
  125.     };
  126.     struct ColorSpec        Colours[9] =
  127.     {   /* colour   red   green     blue    description */
  128.         {    0,     0x9,    0x8,    0xA},    // GREY
  129.         {     1,        0x0,    0x0,    0x0},    // BLACK
  130.         {    2,     0xF,    0xF,    0xF},    // WHITE
  131.         {    3,     0xF,    0x7,    0x7},    // RED
  132.         {    4,     0x6,    0x6,    0xF},   // BLUE
  133.         {    5,     0xD,    0xC,    0xE},   // LIGHTGREY
  134.         {    6,     0xF,    0xF,    0x2},   // YELLOW
  135.         {    7,     0xF,    0x2,    0xF},   // PURPLE
  136.         {    -1,        NULL,    NULL,    NULL
  137.     }    };
  138.  
  139.     /* Start of program.
  140.  
  141.     version embedding into executable */
  142.  
  143.     if (0) // that is, never
  144.         printf(VERSION);
  145.  
  146.     if (!(IntuitionBase = (struct IntuitionBase *) OpenLibrary("intuition.library", 37L)))
  147.     {    Write(Output(), OLDKICKSTART, strlen(OLDKICKSTART));
  148.         cleanexit(EXIT_FAILURE);
  149.     }
  150.     if (SysBase->lib_Version < 36L)
  151.     {    DisplayAlert(AT_Recovery, "\0\20\20Report+: Need exec.library V36+!\0", 24);
  152.         cleanexit(EXIT_FAILURE);
  153.     }
  154.     if (!(GadToolsBase = (struct GadToolsBase *) OpenLibrary("gadtools.library", 37L)))
  155.     {    DisplayAlert(AT_Recovery, "\0\20\20Report+: Can't open GadTools.library V37+!\0", 24);
  156.         cleanexit(EXIT_FAILURE);
  157.     }
  158.  
  159.     // From this point onwards, we can be sure we have Kickstart 2.04+...
  160.  
  161.     if (!(ASLBase = (struct ASLBase *) OpenLibrary("asl.library", 0L)))
  162.     {    DisplayAlert(AT_Recovery, "\0\20\20Report+: Can't open ASL.library!\0", 24);
  163.         cleanexit(EXIT_FAILURE);
  164.     }
  165.  
  166.     ProcessPtr = (struct Process *) FindTask(NULL);
  167.  
  168.     /* PREPARE DISPLAY -----------------------------------------------
  169.  
  170.     screen */
  171.  
  172.     if (!(ScreenPtr = (struct Screen *) OpenScreenTags
  173.     (    NULL,
  174.         SA_Width,            640,
  175.         SA_Height,            256,
  176.         SA_Depth,            DEPTH,
  177.         SA_DisplayID,        HIRES_KEY,
  178.         SA_Title,            TITLEBAR,
  179.         SA_Colors,            Colours,
  180.         SA_Font,            &Topaz8,
  181.         SA_Pens,            Pens,
  182.         SA_DetailPen,        BLACK,
  183.         SA_BlockPen,        WHITE,
  184.         TAG_DONE
  185.     )))
  186.     {    DisplayAlert(AT_Recovery, "\0\20\20Report+: Can't open screen!\0", 24);
  187.         cleanexit(EXIT_FAILURE);
  188.     }
  189.     if (!(BkgrndWindowPtr = (struct Window *) OpenWindowTags(NULL,
  190.         WA_Top,                12,
  191.         WA_Width,            640,
  192.         WA_Height,            244,
  193.         WA_IDCMP,           NULL,
  194.         WA_Gadgets,            NULL,
  195.         WA_CustomScreen,    ScreenPtr,
  196.         WA_Activate,        FALSE,
  197.         WA_Title,            NULL,
  198.         WA_Borderless,        TRUE,
  199.         WA_Backdrop,        TRUE,
  200.         TAG_DONE)))
  201.     {    DisplayAlert(AT_Recovery, "\0\20\20Report+: Can't open backdrop window!\0", 24);
  202.         cleanexit(EXIT_FAILURE);
  203.     }
  204.     SetAPen(BkgrndWindowPtr->RPort, BLUE);
  205.     RectFill(BkgrndWindowPtr->RPort, 0, 0, 640, 244);
  206.  
  207.     while(1)
  208.     {    if (page == 0)
  209.             page0();
  210.         elif (page == 1)
  211.             page1();
  212.         elif (page == 2)
  213.             page2();
  214.         elif (page == 3)
  215.             page3();
  216.         elif (page == 4)
  217.             page4();
  218.         elif (page == 5)
  219.             page5();
  220.         elif (page == 6)
  221.             page6();
  222.         else // assumes page == 7
  223.             page7();
  224. }    }
  225.  
  226. void page0(void)
  227. {    // PAGE 0 *************************************************************
  228.  
  229.     gadtools();
  230.     navigate();
  231.  
  232.     // function
  233.     setgadget(260, 24, 0, 0, NULL, PLACETEXT_RIGHT);
  234.     FunctionGadPtr = PrevGadPtr = (struct Gadget *) CreateGadget
  235.     (    MX_KIND,
  236.         PrevGadPtr,
  237.         &Gadget,
  238.         GTMX_Labels, &FunctionOptions,
  239.         GTMX_Active, report.function,
  240.         TAG_DONE
  241.     );
  242.  
  243.     // editor
  244.     if (report.editor[0] == 0)
  245.         if (GetVar("EDITOR", &(report.editor), LONGFIELD, NULL) == -1)
  246.             strcpy(report.editor, "SYS:Tools/MEmacs");
  247.     setgadget(232, 54, 240, 12, "Editor pathname:", NULL);
  248.     EditorGadPtr = PrevGadPtr = (struct Gadget *) CreateGadget
  249.     (    STRING_KIND,
  250.         PrevGadPtr,
  251.         &Gadget,
  252.         GTST_String, &(report.editor),
  253.         GTST_MaxChars, LONGFIELD,
  254.         GA_TabCycle, TRUE,
  255.         TAG_DONE
  256.     );
  257.     // editor...
  258.     setgadget(474, 54, 28, 12, "...", NULL);
  259.     EditorASLGadPtr = PrevGadPtr = (struct Gadget *) CreateGadget
  260.     (    BUTTON_KIND,
  261.         PrevGadPtr,
  262.         &Gadget,
  263.         TAG_DONE
  264.     );
  265.  
  266.     newwindow
  267.     (    640,
  268.         PAGE0HEIGHT,
  269.         "Report+: Function Selection",
  270.         BUTTONIDCMP | MXIDCMP
  271.     );
  272.     loop();
  273.     strcpy
  274.     (    report.editor,
  275.         ((struct StringInfo *) EditorGadPtr->SpecialInfo)->Buffer
  276.     );
  277.     closewindow();
  278. }
  279.  
  280. void page1(void)
  281. {    // PAGE 1 *************************************************************
  282.  
  283.     gadtools();
  284.     navigate();
  285.  
  286.     // type
  287.     setgadget(152, 50, 0, 0, NULL, PLACETEXT_RIGHT);
  288.     TypeGadPtr = PrevGadPtr = (struct Gadget *) CreateGadget
  289.     (    MX_KIND,
  290.         PrevGadPtr,
  291.         &Gadget,
  292.         GTMX_Labels, &RadioOptions1,
  293.         GTMX_Active, report.type,
  294.         TAG_DONE
  295.     );
  296.  
  297.     // summary
  298.     setgadget(64, 30, 512, 12, "Summary:", PLACETEXT_ABOVE);
  299.     SummaryGadPtr = PrevGadPtr = (struct Gadget *) CreateGadget
  300.     (    STRING_KIND,
  301.         PrevGadPtr,
  302.         &Gadget,
  303.         STRINGA_Justification, GACT_STRINGCENTER,
  304.         GTST_String, &(report.subject),
  305.         GTST_MaxChars, LONGFIELD,
  306.         GA_TabCycle, TRUE,
  307.         TAG_DONE
  308.     );
  309.  
  310.     // output
  311.     if (!(report.output[0]))
  312.         strcpy(report.output, "RAM:Report.txt");
  313.     setgadget(242, 88, 240, 12, "Output pathname:", NULL);
  314.     OutputGadPtr = PrevGadPtr = (struct Gadget *) CreateGadget
  315.     (    STRING_KIND,
  316.         PrevGadPtr,
  317.         &Gadget,
  318.         GTST_String, &(report.output),
  319.         GTST_MaxChars, LONGFIELD,
  320.         GA_TabCycle, TRUE,
  321.         TAG_DONE
  322.     );
  323.     // output...
  324.     setgadget(484, 88, 28, 12, "...", NULL);
  325.     OutputASLGadPtr = PrevGadPtr = (struct Gadget *) CreateGadget
  326.     (    BUTTON_KIND,
  327.         PrevGadPtr,
  328.         &Gadget,
  329.         TAG_DONE
  330.     );
  331.  
  332.     newwindow
  333.     (    640,
  334.         PAGE1HEIGHT,
  335.         "Report+: Report Details 1",
  336.         BUTTONIDCMP | MXIDCMP | STRINGIDCMP
  337.     );
  338.     ActivateGadget(SummaryGadPtr, MainWindowPtr, NULL);
  339.  
  340.     loop();
  341.     strcpy
  342.     (    report.subject,
  343.         ((struct StringInfo *) SummaryGadPtr->SpecialInfo)->Buffer
  344.     );
  345.     strcpy
  346.     (    report.output,
  347.         ((struct StringInfo *) OutputGadPtr->SpecialInfo)->Buffer
  348.     );
  349.     closewindow();
  350. }
  351.  
  352. void page2(void)
  353. {    UBYTE    i;
  354.  
  355.     // PAGE 2 *************************************************************
  356.  
  357.     gadtools();
  358.     navigate();
  359.  
  360.     if (report.type == BUG || report.type == ENH)
  361.     {    NewList(&List1);
  362.         for (i = 0; i <= SUBSYSTEMS; i++)
  363.             AddName(&List1, subsystems[i].friendly);
  364.         setgadget(16, 28, 150, 130, "Subsystem:", NULL);
  365.         SubsystemGadPtr = PrevGadPtr = (struct Gadget *) CreateGadget
  366.         (    LISTVIEW_KIND,
  367.             PrevGadPtr,
  368.             &Gadget,
  369.             GTLV_Labels, &List1,
  370.             GTLV_ShowSelected, NULL,
  371.             GTLV_Selected, report.subsystem,
  372.             TAG_DONE
  373.         );
  374.     } else // assumes report.type == COM
  375.     {    // 3rd party product
  376.         setgadget(160, 28, 100, 12, "Third Party Product:", PLACETEXT_ABOVE);
  377.         ThirdGadPtr = PrevGadPtr = (struct Gadget *) CreateGadget
  378.         (    TEXT_KIND,
  379.             PrevGadPtr,
  380.             &Gadget,
  381.             TAG_DONE
  382.         );
  383.         // 3rd party product name
  384.         setgadget(160, 28, 100, 12, "Name:", NULL);
  385.         ThirdNameGadPtr = PrevGadPtr = (struct Gadget *) CreateGadget
  386.         (    STRING_KIND,
  387.             PrevGadPtr,
  388.             &Gadget,
  389.             GTST_String, &(report.thirdname),
  390.             GTST_MaxChars, MEDFIELD,
  391.             GA_TabCycle, TRUE,
  392.             TAG_DONE
  393.         );
  394.  
  395.         // 3rd party product version
  396.         setgadget(160, 40, 100, 12, "Version:", NULL);
  397.         ThirdVerGadPtr = PrevGadPtr = (struct Gadget *) CreateGadget
  398.         (    STRING_KIND,
  399.             PrevGadPtr,
  400.             &Gadget,
  401.             GTST_String, &(report.thirdver),
  402.             GTST_MaxChars, MEDFIELD,
  403.             GA_TabCycle, TRUE,
  404.             TAG_DONE
  405.         );
  406.  
  407.         // 3rd party product manufacturer
  408.         setgadget(160, 52, 100, 12, "Manufacturer:", NULL);
  409.         ThirdManufGadPtr = PrevGadPtr = (struct Gadget *) CreateGadget
  410.         (    STRING_KIND,
  411.             PrevGadPtr,
  412.             &Gadget,
  413.             GTST_String, &(report.thirdmanuf),
  414.             GTST_MaxChars, MEDFIELD,
  415.             GA_TabCycle, TRUE,
  416.             TAG_DONE
  417.         );
  418.     }
  419.  
  420.     if (report.type == BUG || report.type == COM)
  421.     {    // debug tools and wedges
  422.         setgadget(400, 69, 196, 12, "Debug tools and wedges:", NULL);
  423.         DebugGadPtr = PrevGadPtr = (struct Gadget *) CreateGadget
  424.         (    STRING_KIND,
  425.             PrevGadPtr,
  426.             &Gadget,
  427.             GTST_String, &(report.debug),
  428.             GTST_MaxChars, LONGFIELD,
  429.             GA_TabCycle, TRUE,
  430.             TAG_DONE
  431.         );
  432.  
  433.         // classification
  434.         setgadget(308, 24, 0, 0, NULL, PLACETEXT_RIGHT);
  435.         if (report.type == BUG)
  436.         {    if (report.severity == 3)
  437.                 report.severity = 0;
  438.             SeverityGadPtr = PrevGadPtr = (struct Gadget *) CreateGadget
  439.             (    MX_KIND,
  440.                 PrevGadPtr,
  441.                 &Gadget,
  442.                 GTMX_Labels, &RadioOptions2,
  443.                 GTMX_Active, report.severity,
  444.                 TAG_DONE
  445.             );
  446.         } else // assumes (report.type == COM)
  447.             SeverityGadPtr = PrevGadPtr = (struct Gadget *) CreateGadget
  448.             (    MX_KIND,
  449.                 PrevGadPtr,
  450.                 &Gadget,
  451.                 GTMX_Labels, &RadioOptions3,
  452.                 GTMX_Active, report.severity,
  453.                 TAG_DONE
  454.             );
  455.     }
  456.     if (report.type == BUG)
  457.     {    // program version
  458.         setgadget(400, 131, 196, 12, "Program pathname:", NULL);
  459.         PPGadPtr = PrevGadPtr = (struct Gadget *) CreateGadget
  460.         (    STRING_KIND,
  461.             PrevGadPtr,
  462.             &Gadget,
  463.             GTST_String, &(report.pp),
  464.             GTST_MaxChars, LONGFIELD,
  465.             GA_TabCycle, TRUE,
  466.             TAG_DONE
  467.         );
  468.         // program...
  469.         setgadget(598, 131, 28, 12, "...", NULL);
  470.         PPASLGadPtr = PrevGadPtr = (struct Gadget *) CreateGadget
  471.         (    BUTTON_KIND,
  472.             PrevGadPtr,
  473.             &Gadget,
  474.             TAG_DONE
  475.         );
  476.         setgadget(400, 143, 196, 12, "Program version:", NULL);
  477.         PVGadPtr = PrevGadPtr = (struct Gadget *) CreateGadget
  478.         (    STRING_KIND,
  479.             PrevGadPtr,
  480.             &Gadget,
  481.             GTST_String, &(report.pv),
  482.             GTST_MaxChars, LONGFIELD,
  483.             GA_TabCycle, TRUE,
  484.             TAG_DONE
  485.         );
  486.     }
  487.  
  488.     if (report.type == BUG || report.type == COM)
  489.     {    // kickstart version
  490.         if (report.ks[0] == 0)
  491.             if (GetVar("Kickstart", &(report.ks), 6, NULL) == -1)
  492.                 report.ks[0] = 0;
  493.         setgadget(400, 93, 60, 12, "Kickstart version:", NULL);
  494.         KSGadPtr = PrevGadPtr = (struct Gadget *) CreateGadget
  495.         (    STRING_KIND,
  496.             PrevGadPtr,
  497.             &Gadget,
  498.             GTST_String, &(report.ks),
  499.             GTST_MaxChars, 6,
  500.             GA_TabCycle, TRUE,
  501.             STRINGA_Justification, GACT_STRINGRIGHT,
  502.             TAG_DONE
  503.         );
  504.  
  505.         // workbench version
  506.         if (report.wb[0] == 0)
  507.             if (GetVar("Workbench", &(report.wb), 6, NULL) == -1)
  508.                 report.wb[0] = 0;
  509.         setgadget(400, 105, 60, 12, "Workbench version:", NULL);
  510.         WBGadPtr = PrevGadPtr = (struct Gadget *) CreateGadget
  511.         (    STRING_KIND,
  512.             PrevGadPtr,
  513.             &Gadget,
  514.             GTST_String, &(report.wb),
  515.             GTST_MaxChars, 6,
  516.             GA_TabCycle, TRUE,
  517.             STRINGA_Justification, GACT_STRINGRIGHT,
  518.             TAG_DONE
  519.         );
  520.     }
  521.     newwindow
  522.     (    640,
  523.         PAGE2HEIGHT,
  524.         "Report+: Report Details 2",
  525.         BUTTONIDCMP | LISTVIEWIDCMP | MXIDCMP
  526.     );
  527.     ActivateGadget(KSGadPtr, MainWindowPtr, NULL);
  528.  
  529.     loop();
  530.     if (report.type == COM)
  531.     {    strcpy
  532.         (    report.thirdver,
  533.             ((struct StringInfo *) ThirdVerGadPtr->SpecialInfo)->Buffer
  534.         );
  535.         strcpy
  536.         (    report.thirdname,
  537.             ((struct StringInfo *) ThirdNameGadPtr->SpecialInfo)->Buffer
  538.         );
  539.         strcpy
  540.         (    report.thirdmanuf,
  541.             ((struct StringInfo *) ThirdManufGadPtr->SpecialInfo)->Buffer
  542.         );
  543.     } elif (report.type == BUG)
  544.     {    strcpy
  545.         (    report.pp,
  546.             ((struct StringInfo *) PPGadPtr->SpecialInfo)->Buffer
  547.         );
  548.         strcpy
  549.         (    report.pv,
  550.             ((struct StringInfo *) PVGadPtr->SpecialInfo)->Buffer
  551.         );
  552.     }
  553.     strcpy
  554.     (    report.ks,
  555.         ((struct StringInfo *) KSGadPtr->SpecialInfo)->Buffer
  556.     );
  557.     strcpy
  558.     (    report.wb,
  559.         ((struct StringInfo *) WBGadPtr->SpecialInfo)->Buffer
  560.     );
  561.     strcpy
  562.     (    report.debug,
  563.         ((struct StringInfo *) DebugGadPtr->SpecialInfo)->Buffer
  564.     );
  565.     closewindow();
  566. }
  567.  
  568. void page3(void)
  569. {    // PAGE 3 *************************************************************
  570.  
  571.     gadtools();
  572.     navigate();
  573.     if (read("S:Report.sender"))
  574.     {    /*    # Refer: <last>,<first> (<company> ,phone <phone>)<LF>
  575.             # Path: <email><LF>
  576.             # ReferID: <developer><LF> */
  577.  
  578.         offset = 0;
  579.         parse("# Refer: ");
  580.         parse(",");
  581.         strcpy(report.lastname, string);
  582.         parse(" (");
  583.         strcpy(report.firstname, string);
  584.         parse(" ,phone ");
  585.         strcpy(report.company, string);
  586.         parse(")\n# Path: ");
  587.         strcpy(report.phone, string);
  588.         parse("\n# ReferID: ");
  589.         strcpy(report.email, string);
  590.         parse("\n");
  591.         report.developer = atol(string);
  592.     }
  593.  
  594.     // first name
  595.     setgadget(326, 22, 128, 12, "First name:", NULL);
  596.     FirstNameGadPtr = PrevGadPtr = (struct Gadget *) CreateGadget
  597.     (    STRING_KIND,
  598.         PrevGadPtr,
  599.         &Gadget,
  600.         GTST_String, &(report.firstname),
  601.         GTST_MaxChars, MEDFIELD,
  602.         GA_TabCycle, TRUE,
  603.         TAG_DONE
  604.     );
  605.  
  606.     // last name
  607.     setgadget(326, 34, 128, 12, "Last name:", NULL);
  608.     LastNameGadPtr = PrevGadPtr = (struct Gadget *) CreateGadget
  609.     (    STRING_KIND,
  610.         PrevGadPtr,
  611.         &Gadget,
  612.         GTST_String, &(report.lastname),
  613.         GTST_MaxChars, MEDFIELD,
  614.         GA_TabCycle, TRUE,
  615.         TAG_DONE
  616.     );
  617.  
  618.     // company name
  619.     setgadget(326, 46, 128, 12, "Company:", NULL);
  620.     CompanyGadPtr = PrevGadPtr = (struct Gadget *) CreateGadget
  621.     (    STRING_KIND,
  622.         PrevGadPtr,
  623.         &Gadget,
  624.         GTST_String, &(report.company),
  625.         GTST_MaxChars, MEDFIELD,
  626.         GA_TabCycle, TRUE,
  627.         TAG_DONE
  628.     );
  629.  
  630.     // phone
  631.     setgadget(326, 58, 128, 12, "Phone number:", NULL);
  632.     PhoneGadPtr = PrevGadPtr = (struct Gadget *) CreateGadget
  633.     (    STRING_KIND,
  634.         PrevGadPtr,
  635.         &Gadget,
  636.         GTST_String, &(report.phone),
  637.         GTST_MaxChars, MEDFIELD,
  638.         GA_TabCycle, TRUE,
  639.         TAG_DONE
  640.     );
  641.  
  642.     // developer number
  643.     setgadget(326, 70, 128, 12, "Developer number:", NULL);
  644.     DeveloperGadPtr = PrevGadPtr = (struct Gadget *) CreateGadget
  645.     (    INTEGER_KIND,
  646.         PrevGadPtr,
  647.         &Gadget,
  648.         GTIN_Number, report.developer,
  649.         GA_TabCycle, TRUE,
  650.         TAG_DONE
  651.     );
  652.  
  653.     // email
  654.     setgadget(326, 82, 256, 12, "EMail:", NULL);
  655.     EMailGadPtr = PrevGadPtr = (struct Gadget *) CreateGadget
  656.     (    STRING_KIND,
  657.         PrevGadPtr,
  658.         &Gadget,
  659.         GTST_String, &(report.email),
  660.         GTST_MaxChars, MEDFIELD,
  661.         GA_TabCycle, TRUE,
  662.         TAG_DONE
  663.     );
  664.  
  665.     newwindow
  666.     (    640,
  667.         PAGE3HEIGHT,
  668.         "Report+: Sender Details",
  669.         BUTTONIDCMP | STRINGIDCMP
  670.     );
  671.     ActivateGadget(FirstNameGadPtr, MainWindowPtr, NULL);
  672.     loop();
  673.  
  674.     /* write out S:Report.sender
  675.  
  676.     # Refer: <last>,<first> (<company> ,phone <phone>)<LF>
  677.     # Path: <email><LF>
  678.     # ReferID: <developer><LF> */
  679.  
  680.     strcpy(report.refer, "# Refer: ");
  681.     strcat
  682.     (    report.refer,
  683.         ((struct StringInfo *) LastNameGadPtr->SpecialInfo)->Buffer
  684.     );
  685.     strcat(report.refer, ",");
  686.     strcat
  687.     (    report.refer,
  688.         ((struct StringInfo *) FirstNameGadPtr->SpecialInfo)->Buffer
  689.     );
  690.     strcat(report.refer, " (");
  691.     strcat
  692.     (    report.refer,
  693.         ((struct StringInfo *) CompanyGadPtr->SpecialInfo)->Buffer
  694.     );
  695.     strcat(report.refer, " ,phone ");
  696.     strcat
  697.     (    report.refer,
  698.         ((struct StringInfo *) PhoneGadPtr->SpecialInfo)->Buffer
  699.     );
  700.     strcat(report.refer, ")\n");
  701.  
  702.     strcpy(report.path, "# Path: ");
  703.     strcat
  704.     (    report.path,
  705.         ((struct StringInfo *) EMailGadPtr->SpecialInfo)->Buffer
  706.     );
  707.     strcat(report.path, "\n");
  708.  
  709.     strcpy(report.referid, "# ReferID: ");
  710.     stcl_d
  711.     (    string,
  712.         ((struct StringInfo *) DeveloperGadPtr->SpecialInfo)->LongInt
  713.     );
  714.     strcat(report.referid, string);
  715.     strcat(report.referid, "\n");
  716.  
  717.     strcpy(IOBuffer, report.refer);
  718.     strcat(IOBuffer, report.path);
  719.     strcat(IOBuffer, report.referid);
  720.  
  721.     write("S:Report.sender");
  722.     closewindow();
  723. }
  724.  
  725. void page4(void)
  726. {   // PAGE 4 **************************************************************
  727.  
  728.     UBYTE i;
  729.     
  730.     gadtools();
  731.     navigate();
  732.  
  733.     if (read("S:Report.config"))
  734.     {    /*    # Config: <model>,<cpu>,A=AA|ECS-pal|ECS|old-pal|old,
  735.             D=AA|ECS|old,RAM=<chip>megC/<fast>megF,TD=<floppies>,
  736.             HD=<controller>,<cards><LF> */
  737.  
  738.         offset = 0;
  739.         parse("# Config: ");
  740.  
  741.         parse(",");
  742.         report.model = 4;
  743.         for (i = 0; i <= MODELS; i++)
  744.             if (!stricmp(string, ModelOptions[i]))
  745.                 report.model = i;
  746.  
  747.         parse(",A=");
  748.         report.cpu = 1;
  749.         for (i = 0; i <= CPUS; i++)
  750.             if (!stricmp(string, CPUOptions[i]))
  751.                 report.cpu = i;
  752.  
  753.         parse(",D=");
  754.         if (!stricmp(string, "AA"))
  755.             report.agnus = 0;
  756.         elif (!stricmp(string, "ECS-pal"))
  757.             report.agnus = 1;
  758.         elif (!stricmp(string, "ECS"))
  759.             report.agnus = 2;
  760.         elif (!stricmp(string, "old-pal"))
  761.             report.agnus = 3;
  762.         else // if (!stricmp(string, "old"))
  763.             report.agnus = 4;
  764.  
  765.         parse(",RAM=");
  766.         if (!stricmp(string, "AA"))
  767.             report.denise = 0;
  768.         elif (!stricmp(string, "ECS"))
  769.             report.denise = 1;
  770.         else // if (!stricmp(string, "old"))
  771.             report.denise = 2;
  772.  
  773.         parse("megC/");
  774.         strcpy(report.chipram, string);
  775.  
  776.         parse("megF,TD=");
  777.         strcpy(report.fastram, string);
  778.  
  779.         parse(",HD=");
  780.         report.floppies = atol(string);
  781.  
  782.         parse(",");
  783.         strcpy(report.hard, string);
  784.  
  785.         parse("\n");
  786.         strcpy(report.expansion, string);
  787.     }
  788.  
  789.     /* These formal coordinates of these text gadgets must not overlap the
  790.     radio gadgets, otherwise any such overlapped radio gadgets will not be
  791.     selectable. */
  792.  
  793.     // model
  794.     setgadget(64, 30, 100, 0, "Model:", PLACETEXT_ABOVE);
  795.     ModelTextGadPtr = PrevGadPtr = (struct Gadget *) CreateGadget
  796.     (    TEXT_KIND,
  797.         PrevGadPtr,
  798.         &Gadget,
  799.         TAG_DONE
  800.     );
  801.     setgadget(64, 30, 0, 0, NULL, PLACETEXT_RIGHT);
  802.     ModelGadPtr = PrevGadPtr = (struct Gadget *) CreateGadget
  803.     (    MX_KIND,
  804.         PrevGadPtr,
  805.         &Gadget,
  806.         GTMX_Labels, &ModelOptions,
  807.         GTMX_Active, report.model,
  808.         TAG_DONE
  809.     );
  810.  
  811.     // Agnus
  812.     setgadget(192, 30, 100, 0, "Agnus/Alice Type:", PLACETEXT_ABOVE);
  813.     AgnusTextGadPtr = PrevGadPtr = (struct Gadget *) CreateGadget
  814.     (    TEXT_KIND,
  815.         PrevGadPtr,
  816.         &Gadget,
  817.         TAG_DONE
  818.     );
  819.     setgadget(192, 30, 0, 0, NULL, PLACETEXT_RIGHT);
  820.     AgnusGadPtr = PrevGadPtr = (struct Gadget *) CreateGadget
  821.     (    MX_KIND,
  822.         PrevGadPtr,
  823.         &Gadget,
  824.         GTMX_Labels, &AgnusOptions,
  825.         GTMX_Active, report.agnus,
  826.         TAG_DONE
  827.     );
  828.  
  829.     // Denise
  830.     setgadget(384, 30, 100, 0, "Denise/Lisa Type:", PLACETEXT_ABOVE);
  831.     DeniseTextGadPtr = PrevGadPtr = (struct Gadget *) CreateGadget
  832.     (    TEXT_KIND,
  833.         PrevGadPtr,
  834.         &Gadget,
  835.         TAG_DONE
  836.     );
  837.     setgadget(384, 30, 0, 0, NULL, PLACETEXT_RIGHT);
  838.     DeniseGadPtr = PrevGadPtr = (struct Gadget *) CreateGadget
  839.     (    MX_KIND,
  840.         PrevGadPtr,
  841.         &Gadget,
  842.         GTMX_Labels, &DeniseOptions,
  843.         GTMX_Active, report.denise,
  844.         TAG_DONE
  845.     );
  846.  
  847.     // CPU
  848.     setgadget(512, 30, 100, 0, "Processor:", PLACETEXT_ABOVE);
  849.     CPUTextGadPtr = PrevGadPtr = (struct Gadget *) CreateGadget
  850.     (    TEXT_KIND,
  851.         PrevGadPtr,
  852.         &Gadget,
  853.         TAG_DONE
  854.     );
  855.     setgadget(512, 30, 0, 0, NULL, PLACETEXT_RIGHT);
  856.     CPUGadPtr = PrevGadPtr = (struct Gadget *) CreateGadget
  857.     (   MX_KIND,
  858.         PrevGadPtr,
  859.         &Gadget,
  860.         GTMX_Labels, &CPUOptions,
  861.         GTMX_Active, report.cpu,
  862.         TAG_DONE
  863.     );
  864.  
  865.     // chip RAM
  866.     setgadget(400, 98, 64, 12, "Mb", PLACETEXT_RIGHT);
  867.     ChipTextGadPtr = PrevGadPtr = (struct Gadget *) CreateGadget
  868.     (    TEXT_KIND,
  869.         PrevGadPtr,
  870.         &Gadget,
  871.         TAG_DONE
  872.     );
  873.     setgadget(400, 98, 64, 12, "Chip RAM:", NULL);
  874.     ChipGadPtr = PrevGadPtr = (struct Gadget *) CreateGadget
  875.     (    STRING_KIND,
  876.         PrevGadPtr,
  877.         &Gadget,
  878.         GTST_String, &(report.chipram),
  879.         GTST_MaxChars, 4,
  880.         GA_TabCycle, TRUE,
  881.         TAG_DONE
  882.     );
  883.  
  884.     // slow/fast RAM
  885.     setgadget(400, 110, 64, 12, "Mb", PLACETEXT_RIGHT);
  886.     FastTextGadPtr = PrevGadPtr = (struct Gadget *) CreateGadget
  887.     (    TEXT_KIND,
  888.         PrevGadPtr,
  889.         &Gadget,
  890.         TAG_DONE
  891.     );
  892.     setgadget(400, 110, 64, 12, "Slow/fast RAM:", NULL);
  893.     FastGadPtr = PrevGadPtr = (struct Gadget *) CreateGadget
  894.     (    STRING_KIND,
  895.         PrevGadPtr,
  896.         &Gadget,
  897.         GTST_String, &(report.fastram),
  898.         GTST_MaxChars, 4,
  899.         GA_TabCycle, TRUE,
  900.         TAG_DONE
  901.     );
  902.  
  903.     // floppies
  904.     setgadget(400, 122, 64, 12, "Number of floppies:", NULL);
  905.     FloppiesGadPtr = PrevGadPtr = (struct Gadget *) CreateGadget
  906.     (    INTEGER_KIND,
  907.         PrevGadPtr,
  908.         &Gadget,
  909.         GTIN_Number, report.floppies,
  910.         GA_TabCycle, TRUE,
  911.         TAG_DONE
  912.     );
  913.  
  914.     // hard disk controller
  915.     setgadget(400, 134, 128, 12, "Hard disk controller:", NULL);
  916.     HardGadPtr = PrevGadPtr = (struct Gadget *) CreateGadget
  917.     (    STRING_KIND,
  918.         PrevGadPtr,
  919.         &Gadget,
  920.         GTST_String, &(report.hard),
  921.         GTST_MaxChars, MEDFIELD,
  922.         GA_TabCycle, TRUE,
  923.         TAG_DONE
  924.     );
  925.  
  926.     // expansion cards
  927.     setgadget(400, 146, 228, 12, "Expansion cards:", NULL);
  928.     ExpansionGadPtr = PrevGadPtr = (struct Gadget *) CreateGadget
  929.     (    STRING_KIND,
  930.         PrevGadPtr,
  931.         &Gadget,
  932.         GTST_String, &(report.expansion),
  933.         GTST_MaxChars, LONGFIELD,
  934.         GA_TabCycle, TRUE,
  935.         TAG_DONE
  936.     );
  937.  
  938.     newwindow
  939.     (    640,
  940.         PAGE4HEIGHT,
  941.         "Report+: Configuration Details",
  942.         BUTTONIDCMP | STRINGIDCMP | MXIDCMP
  943.     );
  944.     ActivateGadget(ChipGadPtr, MainWindowPtr, NULL);
  945.     loop();
  946.  
  947.     strcpy(report.chipram,   ((struct StringInfo *) ChipGadPtr->SpecialInfo)->Buffer);
  948.     strcpy(report.fastram,   ((struct StringInfo *) FastGadPtr->SpecialInfo)->Buffer);
  949.     strcpy(report.hard,      ((struct StringInfo *) HardGadPtr->SpecialInfo)->Buffer);
  950.     report.floppies           = ((struct StringInfo *) FloppiesGadPtr->SpecialInfo)->LongInt;
  951.     strcpy(report.expansion, ((struct StringInfo *) ExpansionGadPtr->SpecialInfo)->Buffer);
  952.  
  953.     strcpy(report.config, "# Config: ");
  954.     strcpy(string, ModelOptions[report.model]);
  955.     strlwr(string);
  956.     strcat(report.config, string);
  957.     strcat(report.config, ",");
  958.     strcpy(string, CPUOptions[report.cpu]);
  959.     strlwr(string);
  960.     strcat(report.config, string);
  961.     strcat(report.config, ",A=");
  962.     switch(report.agnus)
  963.     {
  964.     case 0:
  965.         strcat(report.config, "AA");
  966.     break;
  967.     case 1:
  968.         strcat(report.config, "ECS-pal");
  969.     break;
  970.     case 2:
  971.         strcat(report.config, "ECS");
  972.     break;
  973.     case 3:
  974.         strcat(report.config, "old-pal");
  975.     break;
  976.     default:
  977.         strcat(report.config, "old");
  978.     break;
  979.     }
  980.     strcat(report.config, ",D=");
  981.     switch(report.denise)
  982.     {
  983.     case 0:
  984.         strcat(report.config, "AA");
  985.     break;
  986.     case 1:
  987.         strcat(report.config, "ECS");
  988.     break;
  989.     default:
  990.         strcat(report.config, "old");
  991.     break;
  992.     }
  993.     strcat(report.config, ",RAM=");
  994.     strcat(report.config, report.chipram);
  995.     strcat(report.config, "megC/");
  996.     strcat(report.config, report.fastram);
  997.     strcat(report.config, "megF,TD=");
  998.     stcl_d(string, report.floppies);
  999.     strcat(report.config, string);
  1000.     strcat(report.config, ",HD=");
  1001.     strcat(report.config, report.hard);
  1002.     strcat(report.config, ",");
  1003.     strcat(report.config, report.expansion);
  1004.     strcat(report.config, "\n");
  1005.  
  1006.     strcpy(IOBuffer, report.config);
  1007.     write("S:Report.config");
  1008.     closewindow();
  1009. }
  1010.  
  1011. void page5(void)
  1012. {    TEXT                weekdaystring[10],
  1013.                         datestring[10],
  1014.                         timestring[9];
  1015.     struct DateTime        DateTime;
  1016.  
  1017.     DateTime.dat_Format        = FORMAT_DOS;
  1018.     DateTime.dat_Flags        = NULL;
  1019.     DateTime.dat_StrDay        = weekdaystring;
  1020.     DateTime.dat_StrDate    = datestring;
  1021.     DateTime.dat_StrTime    = timestring;
  1022.  
  1023.     newwindow
  1024.     (    640,
  1025.         PAGE5HEIGHT,
  1026.         "Report+: Finished Bug Report",
  1027.         BUTTONIDCMP
  1028.     );
  1029.  
  1030. /*        # Subject: <subject><LF>
  1031.         # Type: bug|compat|enhancement<LF>
  1032. 1,3        # Subsystem: <subsystem><LF>
  1033. 2        # ProductName: <name> (vers=<version>)
  1034. 2        # ProductInfo: :<manufacturer>:
  1035.         # Severity: a|b|c|ok|e
  1036. 1        # Release: KS=<version>,WB=<version>,Program=<version>
  1037. 2        # Release: KS=<version>,WB=<version>
  1038.         # Date: <weekday> dd-Mon-yy hh:mm:ss
  1039.         # Refer: <refer>
  1040.         # Path: <path>
  1041.         # ReferID: <referid>
  1042.         # Config: <config>
  1043. 1,2a-c    ### BRIEF BUG DESCRIPTION:
  1044. 1,2a-c    ### BUG GENERATION PROCEDURE OR EXAMPLE:
  1045. 1,2        ### ALSO RUNNING:
  1046.         <debug>
  1047. 1,2        ### IF THIS WORKS DIFFERENTLY ON OTHER VERSIONS OR HARDWARE,
  1048.         EXPLAIN:
  1049. 2a-c    ### WHAT DEVELOPER IS DOING IN THAT AREA OF SW OR HW:    
  1050. 1,2a-c    ### RELATED PROBLEMS:
  1051. 3        ### ENHANCEMENT REQUEST: */
  1052.  
  1053.     strcpy(IOBuffer, "# Subject: ");
  1054.     strcat(IOBuffer, report.subject);
  1055.     strcat(IOBuffer, "\n# Type: ");
  1056.     if (report.type == BUG)
  1057.         strcat(IOBuffer, "bug");
  1058.     elif (report.type == COM)
  1059.         strcat(IOBuffer, "compat");
  1060.     else // assumes (report.type == ENH)
  1061.         strcat(IOBuffer, "enhancement");
  1062.     strcat(IOBuffer, "\n");
  1063.     if (report.type == BUG || report.type == ENH)
  1064.     {    strcat(IOBuffer, "# Subsystem: ");
  1065.         strcat(IOBuffer, subsystems[SUBSYSTEMS - report.subsystem].unfriendly);
  1066.         strcat(IOBuffer, "\n");
  1067.     } else
  1068.     {    strcat(IOBuffer, "# ProductName: ");
  1069.         strcat(IOBuffer, report.thirdname);
  1070.         strcat(IOBuffer, " (vers=");
  1071.         strcat(IOBuffer, report.thirdver);
  1072.         strcat(IOBuffer, ")\n# ProductInfo: :");
  1073.         strcat(IOBuffer, report.thirdmanuf);
  1074.         strcat(IOBuffer, ":\n");
  1075.     }
  1076.     strcat(IOBuffer, "# Severity: ");
  1077.     if (report.type == ENH)
  1078.         strcat(IOBuffer, "e");
  1079.     elif (report.severity == 0)
  1080.         strcat(IOBuffer, "a");
  1081.     elif (report.severity == 1)
  1082.         strcat(IOBuffer, "b");
  1083.     elif (report.severity == 2)
  1084.         strcat(IOBuffer, "c");
  1085.     else // assumes report.severity == 3
  1086.         strcat(IOBuffer, "ok");
  1087.     strcat(IOBuffer, "\n");
  1088.     if (report.type == BUG || report.type == COM)
  1089.     {    strcat(IOBuffer, "# Release: KS=");
  1090.         strcat(IOBuffer, report.ks);
  1091.         strcat(IOBuffer, ",WB=");
  1092.         strcat(IOBuffer, report.wb);
  1093.         if (report.type == BUG)
  1094.         {    strcat(IOBuffer, ",Program=");
  1095.             strcat(IOBuffer, report.pv);
  1096.         }
  1097.         strcat(IOBuffer, "\n");
  1098.     }
  1099.     DateStamp(&(DateTime.dat_Stamp));
  1100.     if (!DateToStr(&DateTime))
  1101.     {    DisplayAlert(AT_Recovery, "\0\20\20Report+: Couldn't convert date!\0", 24);
  1102.         cleanexit(EXIT_FAILURE);
  1103.     }
  1104.     strcat(IOBuffer, "# Date: ");
  1105.     strcat(IOBuffer, weekdaystring);
  1106.     strcat(IOBuffer, " ");
  1107.     strcat(IOBuffer, datestring);
  1108.     strcat(IOBuffer, " ");
  1109.     strcat(IOBuffer, timestring);
  1110.     strcat(IOBuffer, "\n");
  1111.     strcat(IOBuffer, report.refer);
  1112.     strcat(IOBuffer, report.path);
  1113.     strcat(IOBuffer, report.referid);
  1114.     strcat(IOBuffer, report.config);
  1115.         strcat(IOBuffer, "\n");
  1116.     if (report.type == BUG || (report.type == COM && report.severity != 3))
  1117.     {    strcat
  1118.         (    IOBuffer,
  1119.             "### BRIEF BUG DESCRIPTION:\n\n\n"
  1120.             "### BUG GENERATION PROCEDURE OR EXAMPLE:\n\n\n"
  1121.         );
  1122.     }
  1123.     if (report.type == BUG || report.type == COM)
  1124.     {    strcat(IOBuffer, "### ALSO RUNNING:\n");
  1125.                 strcat(IOBuffer, report.debug);
  1126.         strcat
  1127.         (    IOBuffer,
  1128.             "\n\n### IF THIS WORKS DIFFERENTLY ON "
  1129.             "OTHER VERSIONS OR HARDWARE, EXPLAIN:\n\n\n"
  1130.         );
  1131.     }
  1132.     if (report.type == COM && report.severity != 3)
  1133.     {    strcat
  1134.         (    IOBuffer,
  1135.             "### WHAT DEVELOPER IS DOING IN THAT AREA OF HW OR SW:\n\n\n"
  1136.         );
  1137.     }
  1138.     if (report.type == BUG || (report.type == COM && report.severity != 3))
  1139.         strcat(IOBuffer, "### RELATED PROBLEMS:\n\n\n");
  1140.     elif (report.type == ENH)
  1141.         strcat(IOBuffer, "### ENHANCEMENT REQUEST:\n\n\n");
  1142.  
  1143.     write(report.output);
  1144.     launcheditor();
  1145.  
  1146.     strcpy(string, "Completed report is ");
  1147.     strcat(string, report.output);
  1148.     strcat(string, ".");
  1149.     say(string);
  1150.     strcpy(string, "EMail to: ");
  1151.     if (!(stricmp(subsystems[report.subsystem].unfriendly, "wormwars"))
  1152.     ||  !(stricmp(subsystems[report.subsystem].unfriendly, "report+")))
  1153.         strcat(string, "james_jacobs@altavista.net");
  1154.     elif (report.type == ENH)
  1155.         strcat(string, "suggestions@amiga.com");
  1156.     else
  1157.         strcat(string, "bugs@amiga.com");
  1158.     say(string);
  1159.  
  1160.     loop();
  1161.     cleanexit(EXIT_SUCCESS);
  1162. }
  1163.  
  1164. void cleanexit(SBYTE rc)
  1165. {    /* ASL requesters and the File|About... window are assumed to be
  1166.     already closed. */
  1167.  
  1168.     if (OldWindowPtr)        ProcessPtr->pr_WindowPtr = OldWindowPtr;
  1169.                             closewindow();
  1170.                             FreeNameNodes(&List1);
  1171.                             FreeNameNodes(&List2);
  1172.     if (BkgrndWindowPtr)    CloseWindow(BkgrndWindowPtr);
  1173.     if (ScreenPtr)            CloseScreen(ScreenPtr);
  1174.     if (ASLBase)            CloseLibrary(ASLBase);
  1175.     if (GadToolsBase)        CloseLibrary(GadToolsBase);
  1176.     if (IntuitionBase)    {    OpenWorkBench();
  1177.                             CloseLibrary(IntuitionBase);                }
  1178.                             exit(rc);
  1179.                             
  1180.                             // End of program.
  1181. }
  1182.  
  1183. void clearkybd(void)
  1184. {    struct IntuiMessage* MsgPtr;
  1185.  
  1186.     while (MsgPtr = (struct IntuiMessage *) GT_GetIMsg(MainWindowPtr->UserPort))
  1187.         GT_ReplyIMsg(MsgPtr);
  1188. }
  1189.  
  1190. void AddName(struct List* ListPtr, STRPTR name)
  1191. {    /* RKM Libraries, p. 496:
  1192.     
  1193.     "Allocate a NameNode structure, copy the given name into the structure,
  1194.     then add it [to] the...list." */
  1195.  
  1196.     struct NameNode* NameNodePtr;
  1197.     
  1198.     if (!(NameNodePtr = AllocMem(sizeof(struct NameNode), MEMF_CLEAR)))
  1199.     {    DisplayAlert(AT_Recovery, "\0\20\20Report+: Can't allocate memory for list node!\0", 24);
  1200.         cleanexit(EXIT_FAILURE);
  1201.     }
  1202.     strcpy(NameNodePtr->nn_Data, name);
  1203.     NameNodePtr->nn_Node.ln_Name    = NameNodePtr->nn_Data;
  1204.     NameNodePtr->nn_Node.ln_Type    = NT_USER;
  1205.     NameNodePtr->nn_Node.ln_Pri        = 0;
  1206.     AddHead((struct List *) ListPtr, (struct Node *) NameNodePtr);
  1207. }
  1208. void FreeNameNodes(struct List* ListPtr)
  1209. {    /* RKM Libraries, p. 496:
  1210.     
  1211.     "Free the entire list, including the header. The header is not
  1212.     updated as the list is freed. This function demonstrates how to avoid
  1213.     referencing freed memory when deallocating nodes." */
  1214.  
  1215.     struct NameNode *WorkNodePtr, *NextNodePtr;
  1216.     
  1217.     WorkNodePtr = (struct NameNode *) (ListPtr->lh_Head); // first node
  1218.     while (NextNodePtr = (struct NameNode *) (WorkNodePtr->nn_Node.ln_Succ))
  1219.     {    FreeMem(WorkNodePtr, sizeof(struct NameNode));
  1220.         WorkNodePtr = NextNodePtr;
  1221. }    }
  1222.  
  1223. void gadtools(void)
  1224. {    if (!(Gadget.ng_VisualInfo = VisualInfoPtr = (struct VisualInfo *) GetVisualInfo(ScreenPtr, TAG_DONE)))
  1225.     {    DisplayAlert(AT_Recovery, "\0\20\20Report+: Can't get GadTools visual info!\0", 24);
  1226.         cleanexit(EXIT_FAILURE);
  1227.     }
  1228.     if (!(MenuPtr = (struct Menu *) CreateMenus(NewMenu, GTMN_FrontPen, BLACK, TAG_DONE)))
  1229.     {    DisplayAlert(AT_Recovery, "\0\20\20Worm Wars: Can't create menus!\0", 24);
  1230.         cleanexit(EXIT_FAILURE);
  1231.     }
  1232.     if (!(LayoutMenus(MenuPtr, VisualInfoPtr, TAG_DONE)))
  1233.     {    DisplayAlert(AT_Recovery, "\0\20\20Worm Wars: Can't lay out menus!\0", 24);
  1234.         cleanexit(EXIT_FAILURE);
  1235.     }
  1236.     if (!(PrevGadPtr = (struct Gadget *) CreateContext(&GListPtr)))
  1237.     {    DisplayAlert(AT_Recovery, "\0\20\20Report+: Can't create GadTools context!\0", 24);
  1238.         cleanexit(EXIT_FAILURE);
  1239. }    }
  1240.  
  1241. void newwindow(SWORD width, SWORD height, STRPTR title, ULONG idcmp)
  1242. {    if (!PrevGadPtr)
  1243.     {    DisplayAlert(AT_Recovery, "\0\20\20Report+: Can't create GadTools gadgets!\0", 24);
  1244.         cleanexit(EXIT_FAILURE);
  1245.     }
  1246.     if (!(MainWindowPtr = (struct Window *) OpenWindowTags(NULL,
  1247.         WA_Top,                12 +  94 - (height / 2),
  1248.         WA_Width,            width,
  1249.         WA_Height,            height,
  1250.         WA_IDCMP,           IDCMP_CLOSEWINDOW | IDCMP_MENUPICK |
  1251.                             IDCMP_REFRESHWINDOW | IDCMP_MOUSEBUTTONS |
  1252.                             idcmp,
  1253.         WA_Gadgets,            GListPtr,
  1254.         WA_CustomScreen,    ScreenPtr,
  1255.         WA_Activate,        TRUE,
  1256.         WA_Title,            title,
  1257.         WA_DragBar,            TRUE,
  1258.         WA_CloseGadget,        TRUE,
  1259.         WA_SmartRefresh,    TRUE,
  1260.         TAG_DONE)))
  1261.     {    DisplayAlert(AT_Recovery, "\0\20\20Report+: Can't open window!\0", 24);
  1262.         cleanexit(EXIT_FAILURE);
  1263.     }
  1264.  
  1265.     // redirection of AmigaDOS system requesters
  1266.     OldWindowPtr = ProcessPtr->pr_WindowPtr;
  1267.     ProcessPtr->pr_WindowPtr = (APTR) MainWindowPtr;
  1268.  
  1269.     SetMenuStrip(MainWindowPtr, MenuPtr);
  1270.     GT_RefreshWindow(MainWindowPtr, NULL);
  1271. }
  1272.  
  1273. void fileabout(void)
  1274. {    ABOOL                    done = FALSE;
  1275.     SBYTE                    line;
  1276.     UWORD                    code, qual;
  1277.     ULONG                    class;
  1278.     struct Window*            AboutWindowPtr;
  1279.     struct IntuiMessage*    MsgPtr;
  1280.  
  1281.     if (!(AboutWindowPtr = (struct Window *) OpenWindowTags(NULL,
  1282.     WA_Left,            320 - (ABOUTXPIXEL / 2),
  1283.     WA_Top,                12 + 94 - (ABOUTYPIXEL / 2),
  1284.     WA_Width,            ABOUTXPIXEL,
  1285.     WA_Height,            ABOUTYPIXEL,
  1286.     WA_IDCMP,            IDCMP_CLOSEWINDOW | IDCMP_RAWKEY,
  1287.     WA_Title,            "About Report+",
  1288.     WA_Gadgets,            NULL,
  1289.     WA_CustomScreen,    ScreenPtr,
  1290.     WA_DragBar,            TRUE,
  1291.     WA_CloseGadget,        TRUE,
  1292.     WA_NoCareRefresh,    TRUE,
  1293.     WA_Activate,        TRUE,
  1294.     TAG_DONE)))
  1295.     {    DisplayAlert(AT_Recovery, "\0\20\20Report+: Can't open About... window!\0");
  1296.         cleanexit(EXIT_FAILURE);
  1297.     } else
  1298.     {    SetAPen(AboutWindowPtr->RPort, BLUE);
  1299.         RectFill(AboutWindowPtr->RPort, 8, 13, ABOUTXPIXEL - 9, ABOUTYPIXEL - 5);
  1300.         SetAPen(AboutWindowPtr->RPort, ABOUTSHADOW);
  1301.         Move(AboutWindowPtr->RPort, 7, ABOUTYPIXEL - 4);
  1302.         Draw(AboutWindowPtr->RPort, 7, 12);
  1303.         Draw(AboutWindowPtr->RPort, ABOUTXPIXEL - 8, 12);
  1304.         SetAPen(AboutWindowPtr->RPort, ABOUTSHINE);
  1305.         Draw(AboutWindowPtr->RPort, ABOUTXPIXEL - 8, ABOUTYPIXEL - 4);
  1306.         Draw(AboutWindowPtr->RPort, 8, ABOUTYPIXEL - 4);
  1307.         SetAPen(AboutWindowPtr->RPort, BLACK);
  1308.         SetDrMd(AboutWindowPtr->RPort, JAM1);
  1309.         for (line = 0; line <= ABOUTLINES; line++)
  1310.         {    Move(AboutWindowPtr->RPort, about[line].x, about[line].y);
  1311.             Text(AboutWindowPtr->RPort, about[line].text, (SBYTE) strlen(about[line].text));
  1312.         }
  1313.         DrawBevelBox(AboutWindowPtr->RPort, 18, 21, 48, 23, GT_VisualInfo, VisualInfoPtr);
  1314.         DrawImage(AboutWindowPtr->RPort, &About, 20, 22);
  1315.  
  1316.         while(!done)
  1317.         {    Wait(1L << AboutWindowPtr->UserPort->mp_SigBit);
  1318.             while (MsgPtr = (struct IntuiMessage *) GetMsg(AboutWindowPtr->UserPort))
  1319.             {    class = MsgPtr->Class;
  1320.                 code  = MsgPtr->Code;
  1321.                 qual  = MsgPtr->Qualifier;
  1322.                 ReplyMsg(MsgPtr);
  1323.                 switch(class)
  1324.                 {
  1325.                 case IDCMP_CLOSEWINDOW:
  1326.                     done = TRUE;
  1327.                     break;
  1328.                 case IDCMP_RAWKEY:
  1329.                     if ((!(qual & IEQUALIFIER_REPEAT)) && code < KEYUP && (code < FIRSTQUALIFIER || code > LASTQUALIFIER))
  1330.                         done = TRUE;
  1331.                     break;
  1332.                 default:
  1333.                     break;
  1334.         }   }   }
  1335.         CloseWindow(AboutWindowPtr);
  1336.         AboutWindowPtr = NULL;
  1337.         clearkybd();
  1338. }    }
  1339.  
  1340. void closewindow(void)
  1341. {    if (MainWindowPtr)
  1342.     {    clearkybd();
  1343.         ClearMenuStrip(MainWindowPtr);
  1344.         CloseWindow(MainWindowPtr);
  1345.         MainWindowPtr = NULL;
  1346.     }
  1347.     if (GListPtr)
  1348.     {    FreeGadgets(GListPtr);
  1349.         GListPtr = NULL;
  1350.     }
  1351.     if (MenuPtr)
  1352.     {    FreeMenus(MenuPtr);
  1353.         MenuPtr = NULL;
  1354.     }
  1355.     if (VisualInfoPtr)
  1356.     {    FreeVisualInfo(VisualInfoPtr);
  1357.         VisualInfoPtr = NULL;
  1358. }    }
  1359.  
  1360. void asl(void)
  1361. {    struct FileRequester* ASLRqPtr;
  1362.  
  1363.     if (!(ASLRqPtr = AllocAslRequestTags(ASL_FileRequest, ASL_Pattern, "~(#?.info)", ASL_Window, MainWindowPtr, TAG_DONE)))
  1364.     {    DisplayAlert(AT_Recovery, "\0\20\20Report+: Can't create ASL request!\0", 24);
  1365.         cleanexit(EXIT_FAILURE);
  1366.     }
  1367.     if (AslRequestTags(ASLRqPtr, ASL_Hail, "Report+ file selector", ASL_FuncFlags, FILF_PATGAD, TAG_DONE) && *(ASLRqPtr->rf_File) != 0)
  1368.     {    strcpy(aslresult, ASLRqPtr->rf_Dir);
  1369.         AddPart(aslresult, ASLRqPtr->rf_File, 254);
  1370.     }
  1371.     if (ASLRqPtr)
  1372.     {    FreeAslRequest(ASLRqPtr);
  1373.         ASLRqPtr = NULL;
  1374. }    }
  1375.  
  1376. void loop(void)
  1377. {    SBYTE                    oldpage = page;
  1378.     struct Gadget*            addr;
  1379.     struct MenuItem*        ItemPtr;
  1380.     struct IntuiMessage*    MsgPtr;
  1381.     UWORD                    code, qual;
  1382.     ULONG                    class;
  1383.  
  1384.     while (page == oldpage)
  1385.     {    Wait(1L << MainWindowPtr->UserPort->mp_SigBit);
  1386.         while (MsgPtr = (struct IntuiMessage *) GT_GetIMsg(MainWindowPtr->UserPort))
  1387.         {    class = MsgPtr->Class;
  1388.             code  = MsgPtr->Code;
  1389.             qual  = MsgPtr->Qualifier;
  1390.             addr  = MsgPtr->IAddress;
  1391.             GT_ReplyIMsg(MsgPtr);
  1392.             if (page == 6)
  1393.             {   if (((struct StringInfo *) ShortGadPtr->SpecialInfo)->Buffer[0])
  1394.                     GT_SetGadgetAttrs
  1395.                     (    NextGadPtr,
  1396.                         MainWindowPtr,
  1397.                         NULL,
  1398.                         GA_Disabled, FALSE,
  1399.                         TAG_DONE
  1400.                     );
  1401.                 else
  1402.                     GT_SetGadgetAttrs
  1403.                     (    NextGadPtr,
  1404.                         MainWindowPtr,
  1405.                         NULL,
  1406.                         GA_Disabled, TRUE,
  1407.                         TAG_DONE
  1408.                     );
  1409.             }
  1410.             switch(class)
  1411.             {
  1412.             case IDCMP_MENUPICK:
  1413.                 while (code != MENUNULL)
  1414.                 {    ItemPtr = ItemAddress(MenuPtr, code);
  1415.                     switch (MENUNUM(code))
  1416.                     {
  1417.                     case MN_PROJECT:
  1418.                         switch (ITEMNUM(code))
  1419.                         {
  1420.                         case IN_ABOUT:
  1421.                             fileabout();
  1422.                             break;
  1423.                         case IN_QUIT:
  1424.                             cleanexit(EXIT_SUCCESS);
  1425.                             break;
  1426.                         default:
  1427.                             break;
  1428.                         }
  1429.                         break;
  1430.                     default:
  1431.                         break;
  1432.                     }
  1433.                     code = ItemPtr->NextSelect;
  1434.                 }
  1435.                 break;
  1436.             case IDCMP_CLOSEWINDOW:
  1437.                 cleanexit(EXIT_SUCCESS);
  1438.                 break;
  1439.             case IDCMP_REFRESHWINDOW:
  1440.                 GT_BeginRefresh(MainWindowPtr);
  1441.                 GT_EndRefresh(MainWindowPtr, TRUE);
  1442.                 break;
  1443.             case IDCMP_GADGETDOWN:
  1444.                 // radio gadgets
  1445.                 switch(page)
  1446.                 {
  1447.                 case 0:
  1448.                     if (addr == FunctionGadPtr)
  1449.                         report.function = code;
  1450.                 break;
  1451.                 case 1:
  1452.                     if (addr == TypeGadPtr)
  1453.                         report.type = code;
  1454.                 break;
  1455.                 case 2:
  1456.                     if (addr == SeverityGadPtr)
  1457.                         report.severity = code;
  1458.                 break;
  1459.                 case 4:
  1460.                     if (addr == ModelGadPtr)
  1461.                         report.model = code;
  1462.                     elif (addr == CPUGadPtr)
  1463.                         report.cpu = code;
  1464.                     elif (addr == DeniseGadPtr)
  1465.                         report.denise = code;
  1466.                     elif (addr == AgnusGadPtr)
  1467.                     {    report.agnus = code;
  1468.                         if (code == 0)
  1469.                         {    report.denise = 0;
  1470.                             GT_SetGadgetAttrs
  1471.                             (    DeniseGadPtr,
  1472.                                 MainWindowPtr,
  1473.                                 NULL,
  1474.                                 GTMX_Active, 0,
  1475.                                 TAG_DONE
  1476.                             );
  1477.                         } elif (code == 1 || code == 2)
  1478.                         {    report.denise = 1;
  1479.                             GT_SetGadgetAttrs
  1480.                             (    DeniseGadPtr,
  1481.                                 MainWindowPtr,
  1482.                                 NULL,
  1483.                                 GTMX_Active, 1,
  1484.                                 TAG_DONE
  1485.                             );
  1486.                         } else // assumes (code == 3 || code == 4)
  1487.                         {    report.denise = 2;
  1488.                             GT_SetGadgetAttrs
  1489.                             (    DeniseGadPtr,
  1490.                                 MainWindowPtr,
  1491.                                 NULL,
  1492.                                 GTMX_Active, 2,
  1493.                                 TAG_DONE
  1494.                             );
  1495.                     }    }
  1496.                 break;
  1497.                 default:
  1498.                 break;
  1499.             }
  1500.             break;
  1501.             case IDCMP_GADGETUP:
  1502.                 // buttons, listviews
  1503.                 if (addr == NextGadPtr)
  1504.                 {    if (page == 0 && report.function == 1)
  1505.                         page = 6;
  1506.                     else page++;
  1507.                 }
  1508.                 elif (addr == PreviousGadPtr)
  1509.                     page--;
  1510.                 else
  1511.                 {    switch(page)
  1512.                     {
  1513.                     case 0:
  1514.                         if (addr == EditorASLGadPtr)
  1515.                         {    asl();
  1516.                             GT_SetGadgetAttrs
  1517.                             (    EditorGadPtr,
  1518.                                 MainWindowPtr,
  1519.                                 NULL,
  1520.                                 GTST_String, aslresult,
  1521.                                 TAG_DONE
  1522.                             );
  1523.                         }
  1524.                     break;
  1525.                     case 1:
  1526.                                         case 6:
  1527.                         if (addr == OutputASLGadPtr)
  1528.                         {    asl();
  1529.                             GT_SetGadgetAttrs
  1530.                             (    OutputGadPtr,
  1531.                                 MainWindowPtr,
  1532.                                 NULL,
  1533.                                 GTST_String, aslresult,
  1534.                                 TAG_DONE
  1535.                             );
  1536.                         }
  1537.                     break;
  1538.                     case 2:
  1539.                         if (addr == PPGadPtr)
  1540.                             refreshpv();
  1541.                         elif (addr == PPASLGadPtr)
  1542.                         {    asl();
  1543.                             GT_SetGadgetAttrs
  1544.                             (    PPGadPtr,
  1545.                                 MainWindowPtr,
  1546.                                 NULL,
  1547.                                 GTST_String, aslresult,
  1548.                                 TAG_DONE
  1549.                             );
  1550.                             refreshpv();
  1551.                         } elif (addr == SubsystemGadPtr)
  1552.                         {    /* code is the position within the list.
  1553.                             The list goes backwards, ie. Z-A. */
  1554.                             report.subsystem = code;
  1555.                             printf("!%d!", code);
  1556.                         }
  1557.                     break;
  1558.                     default:
  1559.                     break;
  1560.                 }    }
  1561.             break;
  1562.             default:
  1563.             break;
  1564. }    }    }    }
  1565.  
  1566. void refreshpv(void)
  1567. {    UBYTE    i;
  1568.     BPTR    FileHandle;
  1569.  
  1570.     strcpy(string, "C:Version ");
  1571.     strcat
  1572.     (    string,
  1573.         ((struct StringInfo *) PPGadPtr->SpecialInfo)->Buffer
  1574.     );
  1575.     if (!(FileHandle = (BPTR) Open("T:ReportPlus.temp", MODE_NEWFILE)))
  1576.     {    DisplayAlert(AT_Recovery, "\0\20\20Report+: Can't open T:ReportPlus.temp for writing!\0", 24);
  1577.         cleanexit(EXIT_FAILURE);
  1578.     }
  1579.     if (!Execute(string, NULL, FileHandle))
  1580.     {    DisplayAlert(AT_Recovery, "\0\20\20Report+: Can't execute C:Version!\0", 24);
  1581.         cleanexit(EXIT_FAILURE);
  1582.     }
  1583.     if (!Close(FileHandle))
  1584.     {    DisplayAlert(AT_Recovery, "\0\20\20Report+: Can't close T:ReportPlus.temp for writing!\0", 24);
  1585.         cleanexit(EXIT_FAILURE);
  1586.     }
  1587.     if (!(FileHandle = (BPTR) Open("T:ReportPlus.temp", MODE_OLDFILE)))
  1588.     {    DisplayAlert(AT_Recovery, "\0\20\20Report+: Can't open T:ReportPlus.temp for reading!\0", 24);
  1589.         cleanexit(EXIT_FAILURE);
  1590.     }
  1591.     if (Read(FileHandle, string, 64) == -1)
  1592.     {    DisplayAlert(AT_Recovery, "\0\20\20Report+: Can't read T:ReportPlus.temp!\0", 24);
  1593.         cleanexit(EXIT_FAILURE);
  1594.     }
  1595.     if (!Close(FileHandle))
  1596.     {    DisplayAlert(AT_Recovery, "\0\20\20Report+: Can't close T:ReportPlus.temp for reading!\0", 24);
  1597.         cleanexit(EXIT_FAILURE);
  1598.     }
  1599.     DeleteFile("T:ReportPlus.temp"); // returns FALSE for failure
  1600.     for (i = 0; i <= MEDFIELD; i++)
  1601.         if (string[i] == LF)
  1602.         {    string[i] = 0;
  1603.             break;
  1604.         }
  1605.     GT_SetGadgetAttrs
  1606.     (    PVGadPtr,
  1607.         MainWindowPtr,
  1608.         NULL,
  1609.         GTST_String, string,
  1610.         TAG_DONE
  1611.     );
  1612. }
  1613.  
  1614. void navigate(void)
  1615. {    // Never called by page5() or page7().
  1616.     
  1617.     // previous
  1618.     
  1619.     if (page >= 2 && page <= 4)
  1620.     {    switch(page)
  1621.         {
  1622.         case 2:
  1623.             setgadget(10, PAGE2HEIGHT - 16, 304, 12, "Previous", NULL);
  1624.         break;
  1625.         case 3:
  1626.             setgadget(10, PAGE3HEIGHT - 16, 304, 12, "Previous", NULL);
  1627.         break;
  1628.         case 4:
  1629.             setgadget(10, PAGE4HEIGHT - 16, 304, 12, "Previous", NULL);
  1630.         break;
  1631.         default:
  1632.         break;
  1633.         }
  1634.         PreviousGadPtr = PrevGadPtr = (struct Gadget *) CreateGadget
  1635.         (    BUTTON_KIND,
  1636.             PrevGadPtr,
  1637.             &Gadget,
  1638.             TAG_DONE
  1639.         );
  1640.     }
  1641.  
  1642.     // next
  1643.     switch(page)
  1644.     {
  1645.     case 0:
  1646.         setgadget( 10, PAGE0HEIGHT - 16, 620, 12, "Begin", NULL);
  1647.     break;
  1648.     case 1:
  1649.         setgadget( 10, PAGE1HEIGHT - 16, 620, 12, "Next", NULL);
  1650.     break;
  1651.     case 2:
  1652.         setgadget(326, PAGE2HEIGHT - 16, 304, 12, "Next", NULL);
  1653.     break;
  1654.     case 3:
  1655.         setgadget(326, PAGE3HEIGHT - 16, 304, 12, "Next", NULL);
  1656.     break;
  1657.     case 4:
  1658.         setgadget(326, PAGE4HEIGHT - 16, 304, 12, "Finish", NULL);
  1659.     break;
  1660.     case 6:
  1661.         setgadget( 10, PAGE6HEIGHT - 16, 620, 12, "Finish", NULL);
  1662.     break;
  1663.     default:
  1664.     break;
  1665.     }
  1666.     if (page == 6)
  1667.     {    NextGadPtr = PrevGadPtr = (struct Gadget *) CreateGadget
  1668.         (    BUTTON_KIND,
  1669.             PrevGadPtr,
  1670.             &Gadget,
  1671.             GA_Disabled, TRUE,
  1672.             TAG_DONE
  1673.         );
  1674.     } else
  1675.     {    NextGadPtr = PrevGadPtr = (struct Gadget *) CreateGadget
  1676.         (    BUTTON_KIND,
  1677.             PrevGadPtr,
  1678.             &Gadget,
  1679.             TAG_DONE
  1680.         );
  1681. }    }
  1682.  
  1683. void setgadget(WORD leftx, WORD topy, WORD width, WORD height, STRPTR text,
  1684.     ULONG flags)
  1685. {    Gadget.ng_LeftEdge            = leftx;
  1686.     Gadget.ng_TopEdge            = topy;
  1687.     Gadget.ng_Width                = width;
  1688.     Gadget.ng_Height            = height;
  1689.     Gadget.ng_GadgetText        = text;
  1690.     Gadget.ng_Flags                = flags;
  1691. }
  1692.  
  1693. void parse(STRPTR terminator)
  1694. {    ABOOL done = FALSE;
  1695.     ULONG suboffset;
  1696.  
  1697.     suboffset = offset;
  1698.     while (!done)
  1699.     {    string[offset - suboffset] = IOBuffer[offset];
  1700.         if (!(strncmp(&(IOBuffer[offset]), terminator, strlen(terminator))))
  1701.         {    string[offset - suboffset] = 0;
  1702.             offset += strlen(terminator);
  1703.             done = TRUE;
  1704.         } else if (offset > strlen(IOBuffer))
  1705.         {    // failure
  1706.             string[0] = 0;
  1707.             done = TRUE;
  1708.         } else offset++;
  1709. }    }
  1710.  
  1711. ABOOL read(STRPTR pathname)
  1712. {    BPTR FileHandle;
  1713.  
  1714.     if (!(FileHandle = (BPTR) Open(pathname, MODE_OLDFILE)))
  1715.         return FALSE;
  1716.     if (Read(FileHandle, IOBuffer, VLONGFIELD) == -1)
  1717.     {    Close(FileHandle);
  1718.         return FALSE;
  1719.     }
  1720.     Close(FileHandle);
  1721.     return TRUE;
  1722. }
  1723.  
  1724. void write(STRPTR pathname)
  1725. {    BPTR FileHandle;
  1726.  
  1727.     if (!(FileHandle = (BPTR) Open(pathname, MODE_NEWFILE)))
  1728.     {    DisplayAlert(AT_Recovery, "\0\20\20Report+: Can't open file for writing!\0", 24);
  1729.         cleanexit(EXIT_FAILURE);
  1730.     }
  1731.     if (Write(FileHandle, IOBuffer, strlen(IOBuffer)) == -1)
  1732.     {    DisplayAlert(AT_Recovery, "\0\20\20Report+: Can't write to file!\0", 24);
  1733.         Close(FileHandle);
  1734.         cleanexit(EXIT_FAILURE);
  1735.     }
  1736.     if (!Close(FileHandle))
  1737.     {    DisplayAlert(AT_Recovery, "\0\20\20Report+: Can't close file for writing!\0", 24);
  1738.         cleanexit(EXIT_FAILURE);
  1739. }    }
  1740.  
  1741. void page6(void)
  1742. {    // PAGE 6 *************************************************************
  1743.  
  1744.     gadtools();
  1745.     navigate();
  1746.  
  1747.     // output
  1748.     if (!(report.output[0]))
  1749.         strcpy(report.output, "RAM:.readme");
  1750.     setgadget(150, 22, 320, 12, "Output pathname:", NULL);
  1751.     OutputGadPtr = PrevGadPtr = (struct Gadget *) CreateGadget
  1752.     (    STRING_KIND,
  1753.         PrevGadPtr,
  1754.         &Gadget,
  1755.         GTST_String, &(report.output),
  1756.         GTST_MaxChars, LONGFIELD,
  1757.         GA_TabCycle, TRUE,
  1758.         GA_Immediate, TRUE,
  1759.         TAG_DONE
  1760.     );
  1761.     // output...
  1762.     setgadget(472, 22, 28, 12, "...", NULL);
  1763.     OutputASLGadPtr = PrevGadPtr = (struct Gadget *) CreateGadget
  1764.     (    BUTTON_KIND,
  1765.         PrevGadPtr,
  1766.         &Gadget,
  1767.         TAG_DONE
  1768.     );
  1769.  
  1770.     setgadget(150, 46, 350, 12, "Short:", NULL);
  1771.     ShortGadPtr = PrevGadPtr = (struct Gadget *) CreateGadget
  1772.     (    STRING_KIND,
  1773.         PrevGadPtr,
  1774.         &Gadget,
  1775.         GTST_String, &(report.amishort),
  1776.         GTST_MaxChars, 40,
  1777.         GA_TabCycle, TRUE,
  1778.         GA_Immediate, TRUE,
  1779.         TAG_DONE
  1780.     );
  1781.  
  1782.     setgadget(150, 58, 350, 12, "Uploader:", NULL);
  1783.     UploaderGadPtr = PrevGadPtr = (struct Gadget *) CreateGadget
  1784.     (    STRING_KIND,
  1785.         PrevGadPtr,
  1786.         &Gadget,
  1787.         GTST_String, &(report.amiuploader),
  1788.         GTST_MaxChars, 40,
  1789.         GA_TabCycle, TRUE,
  1790.         GA_Immediate, TRUE,
  1791.         TAG_DONE
  1792.     );
  1793.  
  1794.     setgadget(150, 70, 350, 12, "Author:", NULL);
  1795.     AuthorGadPtr = PrevGadPtr = (struct Gadget *) CreateGadget
  1796.     (    STRING_KIND,
  1797.         PrevGadPtr,
  1798.         &Gadget,
  1799.         GTST_String, &(report.amiauthor),
  1800.         GTST_MaxChars, 40,
  1801.         GA_TabCycle, TRUE,
  1802.         GA_Immediate, TRUE,
  1803.         TAG_DONE
  1804.     );
  1805.  
  1806.     setgadget(150, 82, 350, 12, "Type:", NULL);
  1807.     AmiTypeGadPtr = PrevGadPtr = (struct Gadget *) CreateGadget
  1808.     (    STRING_KIND,
  1809.         PrevGadPtr,
  1810.         &Gadget,
  1811.         GTST_String, &(report.amitype),
  1812.         GTST_MaxChars, 40,
  1813.         GA_TabCycle, TRUE,
  1814.         GA_Immediate, TRUE,
  1815.         TAG_DONE
  1816.     );
  1817.  
  1818.     setgadget(150, 94, 350, 12, "Replaces:", NULL);
  1819.     ReplacesGadPtr = PrevGadPtr = (struct Gadget *) CreateGadget
  1820.     (    STRING_KIND,
  1821.         PrevGadPtr,
  1822.         &Gadget,
  1823.         GTST_String, &(report.amireplaces),
  1824.         GTST_MaxChars, 40,
  1825.         GA_TabCycle, TRUE,
  1826.         GA_Immediate, TRUE,
  1827.         TAG_DONE
  1828.     );
  1829.  
  1830.     setgadget(150, 106, 350, 12, "Requires:", NULL);
  1831.     RequiresGadPtr = PrevGadPtr = (struct Gadget *) CreateGadget
  1832.     (    STRING_KIND,
  1833.         PrevGadPtr,
  1834.         &Gadget,
  1835.         GTST_String, &(report.amirequires),
  1836.         GTST_MaxChars, 40,
  1837.         GA_TabCycle, TRUE,
  1838.         GA_Immediate, TRUE,
  1839.         TAG_DONE
  1840.     );
  1841.  
  1842.     setgadget(150, 118, 350, 12, "Version:", NULL);
  1843.     VersionGadPtr = PrevGadPtr = (struct Gadget *) CreateGadget
  1844.     (    STRING_KIND,
  1845.         PrevGadPtr,
  1846.         &Gadget,
  1847.         GTST_String, &(report.amiversion),
  1848.         GTST_MaxChars, 40,
  1849.         GA_TabCycle, TRUE,
  1850.         GA_Immediate, TRUE,
  1851.         TAG_DONE
  1852.     );
  1853.  
  1854.     setgadget(150, 130, 350, 12, "Distribution:", NULL);
  1855.     DistributionGadPtr = PrevGadPtr = (struct Gadget *) CreateGadget
  1856.     (    STRING_KIND,
  1857.         PrevGadPtr,
  1858.         &Gadget,
  1859.         GTST_String, &(report.amidistribution),
  1860.         GTST_MaxChars, 40,
  1861.         GA_TabCycle, TRUE,
  1862.         GA_Immediate, TRUE,
  1863.         TAG_DONE
  1864.     );
  1865.  
  1866.     newwindow
  1867.     (    640,
  1868.         PAGE6HEIGHT,
  1869.         "Report+: Aminet Readme Details",
  1870.         BUTTONIDCMP | STRINGIDCMP
  1871.     );
  1872.     ActivateGadget(OutputGadPtr, MainWindowPtr, NULL);
  1873.     loop();
  1874.  
  1875.     strcpy
  1876.     (    report.output,
  1877.         ((struct StringInfo *) OutputGadPtr->SpecialInfo)->Buffer
  1878.     );
  1879.     strcpy
  1880.     (    report.amishort,
  1881.         ((struct StringInfo *) ShortGadPtr->SpecialInfo)->Buffer
  1882.     );
  1883.     strcpy
  1884.     (    report.amiuploader,
  1885.         ((struct StringInfo *) UploaderGadPtr->SpecialInfo)->Buffer
  1886.     );
  1887.     strcpy
  1888.     (    report.amiauthor,
  1889.         ((struct StringInfo *) AuthorGadPtr->SpecialInfo)->Buffer
  1890.     );
  1891.     strcpy
  1892.     (    report.amitype,
  1893.         ((struct StringInfo *) AmiTypeGadPtr->SpecialInfo)->Buffer
  1894.     );
  1895.     strcpy
  1896.     (    report.amireplaces,
  1897.         ((struct StringInfo *) ReplacesGadPtr->SpecialInfo)->Buffer
  1898.     );
  1899.     strcpy
  1900.     (    report.amirequires,
  1901.         ((struct StringInfo *) RequiresGadPtr->SpecialInfo)->Buffer
  1902.     );
  1903.     strcpy
  1904.     (    report.amiversion,
  1905.         ((struct StringInfo *) VersionGadPtr->SpecialInfo)->Buffer
  1906.     );
  1907.     strcpy
  1908.     (    report.amidistribution,
  1909.         ((struct StringInfo *) DistributionGadPtr->SpecialInfo)->Buffer
  1910.     );
  1911.     closewindow();
  1912. }
  1913.  
  1914. void page7(void)
  1915. {    newwindow
  1916.     (    640,
  1917.         PAGE7HEIGHT,
  1918.         "Report+: Finished Aminet Readme",
  1919.         BUTTONIDCMP
  1920.     );
  1921.  
  1922.     /*    Short:        <short>
  1923.         Uploader:     <uploader>
  1924.         Author:       <author>
  1925.         Type:         <type>
  1926.         Replaces:     <replaces>
  1927.         Requires:     <requires>
  1928.         Version:      <version>
  1929.         Distribution: <distribution>
  1930.         
  1931.         <description> */
  1932.  
  1933.     strcpy(IOBuffer, "Short:        ");
  1934.     strcat(IOBuffer, report.amishort);
  1935.     strcat(IOBuffer, "\n");
  1936.     if (report.amiuploader[0])
  1937.     {    strcat(IOBuffer, "Uploader:     ");
  1938.         strcat(IOBuffer, report.amiuploader);
  1939.         strcat(IOBuffer, "\n");
  1940.     }
  1941.     if (report.amiauthor[0])
  1942.     {    strcat(IOBuffer, "Author:       ");
  1943.         strcat(IOBuffer, report.amiauthor);
  1944.         strcat(IOBuffer, "\n");
  1945.     }
  1946.     if (report.amitype[0])
  1947.     {    strcat(IOBuffer, "Type:         ");
  1948.         strcat(IOBuffer, report.amitype);
  1949.         strcat(IOBuffer, "\n");
  1950.     }
  1951.     if (report.amireplaces[0])
  1952.     {    strcat(IOBuffer, "Type:         ");
  1953.         strcat(IOBuffer, report.amireplaces);
  1954.         strcat(IOBuffer, "\n");
  1955.     }
  1956.     if (report.amirequires[0])
  1957.     {    strcat(IOBuffer, "Requires:     ");
  1958.         strcat(IOBuffer, report.amirequires);
  1959.         strcat(IOBuffer, "\n");
  1960.     }
  1961.     if (report.amiversion[0])
  1962.     {    strcat(IOBuffer, "Version:      ");
  1963.         strcat(IOBuffer, report.amiversion);
  1964.         strcat(IOBuffer, "\n");
  1965.     }
  1966.     if (report.amidistribution[0])
  1967.     {    strcat(IOBuffer, "Distribution: ");
  1968.         strcat(IOBuffer, report.amidistribution);
  1969.         strcat(IOBuffer, "\n");
  1970.     }
  1971.     strcat(IOBuffer, "\n");
  1972.  
  1973.     write(report.output);
  1974.     launcheditor();
  1975.  
  1976.     strcpy(string, "Completed readme is ");
  1977.     strcat(string, report.output);
  1978.     strcat(string, ".");
  1979.     say(string);
  1980.     say("Upload this readme to Aminet with your submission.");
  1981.  
  1982.     loop();
  1983.     cleanexit(EXIT_SUCCESS);
  1984. }
  1985.  
  1986. void say(STRPTR sentence)
  1987. {    PERSIST SWORD y = 30;
  1988.  
  1989.     Move
  1990.     (    MainWindowPtr->RPort,
  1991.         320 - (strlen(sentence) * 4),
  1992.         y
  1993.     );
  1994.     Text
  1995.     (    MainWindowPtr->RPort,
  1996.         sentence,
  1997.         strlen(sentence)
  1998.     );
  1999.     y += 16;
  2000. }
  2001.  
  2002. void launcheditor(void)
  2003. {    SetAPen(MainWindowPtr->RPort, BLACK);
  2004.     say("Launching editor...");
  2005.     strcpy(string, report.editor);
  2006.     strcat(string, " ");
  2007.     strcat
  2008.     (    string,
  2009.         report.output
  2010.     );
  2011.     if (!Execute(string, NULL, NULL))
  2012.     {    DisplayAlert(AT_Recovery, "\0\20\20Report+: Can't launch editor!\0", 24);
  2013.         cleanexit(EXIT_FAILURE);
  2014. }    }
  2015.  
  2016. // Must have blank line at EOF.
  2017.